package java_thinking.unit_21._21_15;

import net.jcip.annotations.ThreadSafe;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @Desc:   15.6 使用 Treiber 算法构造的非阻塞栈
 *              1.compareAndSet 这个方法与写入 volatile 类型的变量有着相同的内存效果，同样get方法与读取
 *                volatile 类型的变量有着相同的内存效果
 * @author: cww
 * @DateTime: 2019-06-29 14:50
 */
@ThreadSafe
public class ConcurrentStack<E> {
    AtomicReference<Node<E>> top = new AtomicReference<>();
    public void push(E item) {
        Node<E> oldHead;
        Node<E> newHead = new Node<>(item);
        do {
            oldHead = top.get();
            newHead.next = oldHead;
        } while (!top.compareAndSet(oldHead, newHead));
    }

    public E pop() {
        Node<E> newHead;
        Node<E> oldHead;
        do {
            oldHead = top.get();
            if (oldHead == null) {
                return null;
            }
            newHead = oldHead.next;
        } while (!top.compareAndSet(oldHead, newHead));
        return oldHead.item;
    }

    private static class Node<E> {
        public final E item;
        public Node<E> next;
        public Node(E item) {
            this.item = item;
        }
    }
}
